package io.dbw.common.utils;

import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
　* @description: 缓存
　* @author lxc
　* @date 2021/5/11 15:23
*/
@Slf4j
public class CacheUtils {
    private static final ConcurrentHashMap<String, ValueModel> CACHE_MAP = new ConcurrentHashMap<>();
    /**
     * 线程移除过期时间的数据
     */
    private static ScheduledExecutorService swapExpiredPool = new ScheduledThreadPoolExecutor(1);

    private CacheUtils(){}
    /**
     * 	 存储缓存，过期时间如果小于等于0，则表示永不过期
     * @param key
     * @param value
     * @param expire 多久后过期，单位毫秒(ms)
     */
    public void put(String key, Object value, long expire) {
        if (expire <= 0) {
            expire = -1;
        } else {
            expire = System.currentTimeMillis() + expire;
        }
        ValueModel model = new ValueModel(value, expire);
        CACHE_MAP.put(key, model);
    }
    /**
     * 获取缓存
     */
    public Object get(String key) {
        ValueModel model = CACHE_MAP.get(key);
        if (model == null) {
            return null;
        }
        if (!checkExpire(model)) {
            return model.getValue();
        } else {
           // remove(key);
            return null;
        }
    }
 
    /**
     * 检测是否过期
     *
     * @param model
     * @return false 没有过期，true已过期
     */
    private boolean checkExpire(ValueModel model) {
        long expire = model.getExpire();
        if (expire == -1) {
            return false;
        } else {
            return System.currentTimeMillis() > expire;
        }
    }
 
    /**
     * 清除缓存
     */
    public void remove(String key) {
        if (key != null) {
            CACHE_MAP.remove(key);
        }
    }
 
 
    static class ValueModel {
 
        private Object value;
        private long expire;
        
        public Object getValue() {
			return value;
		}

		public void setValue(Object value) {
			this.value = value;
		}

		public long getExpire() {
			return expire;
		}

		public void setExpire(long expire) {
			this.expire = expire;
		}

		ValueModel(Object value, long expire) {
            this.value = value;
            this.expire = expire;
        }
    }



    /**
     * 利用枚举实现单例模式
     */
    public enum Instance {
        INSTANCE ;

        private CacheUtils instance;

        Instance() {
            instance = new CacheUtils();
//            swapExpiredPool.scheduleWithFixedDelay(() -> {
//                log.info("clear cache task start:"+DateUtils.format(new Date(),"yyyy-MM-dd hh:mm:ss.SSS"));
//                long now = System.currentTimeMillis();
//                CACHE_MAP.keySet().forEach(m->{
//                    ValueModel model = CACHE_MAP.get(m);
//                    long expire = model.getExpire();
//                    if (expire != -1 && now > expire) {
//                        CACHE_MAP.remove(m);
//                    }
//                });
//                log.info("clear cache task  end:"+DateUtils.format(new Date(),"yyyy-MM-dd hh:mm:ss.SSS"));
//            }, 1, 2, TimeUnit.HOURS);
        }

        public CacheUtils getInstance() {
            return instance;
        }
    }
}
